<template>
  <home-header />
  <main>
    <!-- 悬浮指令中心按钮 -->
    <div class="fab-cmd-center" @click="showCmdCenter = true" title="快捷指令中心" v-if="gateway_store.debug">
      <el-icon style="font-size: 24px;">
        <Operation />
      </el-icon>
    </div>
    
    <!-- 活跃报警指示器 -->
    <div v-if="activeAlarms.length > 0" class="fab-alarm-indicator" @click="showActiveAlarms" :title="`当前有 ${activeAlarms.length} 个活跃报警`">
      <el-badge :value="activeAlarms.length" :max="99" class="alarm-badge">
        <el-icon style="font-size: 20px; color: #ff4757;">
          <svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg">
            <path d="M512 64c-92.8 0-168 75.2-168 168v200c0 92.8-75.2 168-168 168v64c0 35.2 28.8 64 64 64h128c0 70.4 57.6 128 128 128s128-57.6 128-128h128c35.2 0 64-28.8 64-64v-64c-92.8 0-168-75.2-168-168V232c0-92.8-75.2-168-168-168z" fill="currentColor"/>
          </svg>
        </el-icon>
      </el-badge>
    </div>
    <cmd-center
      v-model="showCmdCenter"
      :send-cmd="sendCmd"
      :is-paused="isWebSocketPaused"
      :current-gateway-id="activeGatewayId"
      @toggle-pause="toggleWebSocketPause"
      @update:current-gateway-id="handleGatewaySwitch"
    />
    <gateway-config-dialog v-model="showGatewayConfigDialog" />
    <div class="home-layout">
      <!-- 左侧 -->
      <div class="left-column">
        <system-info />
        <div class="my_chart">
          <div class="chart-wrapper" :class="{ zoomed: isZoomed && zoomedChartId === 1 }">
            <ChartSection
              :ref="el => chartRefs[1] = el"
              :device-id="device_currentId"
              :title="`${activeGatewayName}-${currentDeviceIndex} - ${$t('message.uv')}`"
              color="#5470c6"
              :data="uvcArr"
              :x-axis-data="xaxisData"
              unit=""
              :zoom-id="1"
              :is-zoomed="isZoomed && zoomedChartId === 1"
              @zoom="handleZoom"
              legend-name="紫外"
            />
          </div>
          <div class="chart-wrapper" :class="{ zoomed: isZoomed && zoomedChartId === 2 }">
            <ChartSection
              :ref="el => chartRefs[2] = el"
              :device-id="device_currentId"
              :title="`${activeGatewayName}-${currentDeviceIndex} - ${$t('message.inf')}`"
              color="#ee6666"
              :data="infArr"
              :x-axis-data="xaxisData1"
              unit="°C"
              :zoom-id="2"
              :is-zoomed="isZoomed && zoomedChartId === 2"
              @zoom="handleZoom"
              legend-name="红外（°C）"
            />
          </div>
        </div>
      </div>

      <!-- 中间 -->
      <div class="middle-column">
        <main class="mainCenter">
          <header class="middle-header">
            <div class="gateway-selector">
              <el-button
                v-for="gateway in gatewayList"
                :key="gateway.id"
                :class="['gateway-btn', { active: activeGatewayId === gateway.id, 'is-disabled': !gateway.isConnected }]"
                @click="handleGatewaySwitch(gateway.id)"
                type="primary"
                :plain="activeGatewayId !== gateway.id"
                :disabled="!gateway.isConnected"
              >
                {{ gateway.name }}-{{ gateway.ip }}
              </el-button>
            </div>
            <div class="description">{{ $t("message.desc") }}</div>
          </header>
          <module-selector
            :module-list="module_store.selectModule"
            @select="taggleDevice"
            :isZoomed="isZoomed"
          />
          <section class="total chart-statistics-section" ref="totalSection" :class="layoutClass">
            <div class="chart-statistics-legend-area">
              <div class="chart-statistics-tip">点击图例查看</div>
              <div class="chart-statistics-title">报警统计</div>
              <!-- 统计级别指示器 -->
              <div class="stats-level-indicator" :class="{ 'gateway-level': isGatewayLevelStats, 'device-level': !isGatewayLevelStats }">
                <span class="level-icon">{{ isGatewayLevelStats ? '🌐' : '📍' }}</span>
                <span class="level-text">{{ isGatewayLevelStats ? '网关统计' : '监测点统计' }}</span>
              </div>
              <div v-for="item in sensorLegend" :key="item.type" @click="onLegendClick(item.type)" :style="{ cursor: 'pointer', margin: '8px 0', color: selectedLegend === item.type ? item.color : '#aaa', fontWeight: selectedLegend === item.type ? 'bold' : 'normal' }">
                <span :style="{ display: 'inline-block', width: '16px', height: '16px', background: item.color, borderRadius: '50%', marginRight: '8px', verticalAlign: 'middle' }"></span>
                {{ item.label }}
              </div>
            </div>
            <aside class="chart-statistics-bar-area chart-container">
              <div ref="history_bar" v-if="barChartData.length > 0" style="width: 100%; height: 100%;"></div>
              <!-- 空状态提示 -->
              <div v-else class="empty-chart-state">
                <div class="empty-icon">
                  <el-icon style="font-size: 48px; color: #909399;">
                    <svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg">
                      <path d="M928 160H96c-17.7 0-32 14.3-32 32v640c0 17.7 14.3 32 32 32h832c17.7 0 32-14.3 32-32V192c0-17.7-14.3-32-32-32zM888 792H136V232h752v560z" fill="currentColor"/>
                      <path d="M424 688c0 4.4-3.6 8-8 8h-48c-4.4 0-8-3.6-8-8V296c0-4.4 3.6-8 8-8h48c4.4 0 8 3.6 8 8v392zM664 688c0 4.4-3.6 8-8 8h-48c-4.4 0-8-3.6-8-8V456c0-4.4 3.6-8 8-8h48c4.4 0 8 3.6 8 8v232zM904 688c0 4.4-3.6 8-8 8h-48c-4.4 0-8-3.6-8-8V616c0-4.4 3.6-8 8-8h48c4.4 0 8 3.6 8 8v72z" fill="currentColor" opacity="0.3"/>
                    </svg>
                  </el-icon>
                </div>
                <div class="empty-text">
                  <p class="empty-title">暂无报警数据</p>
                  <p class="empty-description">{{ isGatewayLevelStats ? '该网关' : '该监测点' }}当前没有报警记录</p>
                  <p class="empty-tip">点击上方图例查看不同类型的报警统计</p>
                </div>
              </div>
            </aside>
          </section>
        </main>
      </div>

      <!-- 右侧 -->
      <div class="right-column">
        <div class="right-charts">
          <div class="chart-wrapper" :class="{ zoomed: isZoomed && zoomedChartId === 3 }">
            <ChartSection
              :ref="el => chartRefs[3] = el"
              :device-id="device_currentId"
              :title="`${activeGatewayName}-${currentDeviceIndex} - ${$t('message.tem')}`"
              color="#73c0de"
              :data="temArr"
              :x-axis-data="xaxisData2"
              unit="°C"
              :zoom-id="3"
              :is-zoomed="isZoomed && zoomedChartId === 3"
              @zoom="handleZoom"
              legend-name="温度（°C）"
            />
          </div>
          <div class="chart-wrapper" :class="{ zoomed: isZoomed && zoomedChartId === 4 }">
            <ChartSection
              :ref="el => chartRefs[4] = el"
              :device-id="device_currentId"
              :title="`${activeGatewayName}-${currentDeviceIndex} - ${$t('message.hum')}`"
              color="#91cc75"
              :data="humArr"
              :x-axis-data="xaxisData2"
              unit="%RH"
              :zoom-id="4"
              :is-zoomed="isZoomed && zoomedChartId === 4"
              @zoom="handleZoom"
              legend-name="湿度（%RH）"
            />
          </div>
          <div class="chart-wrapper" :class="{ zoomed: isZoomed && zoomedChartId === 5 }">
            <ChartSection
              :ref="el => chartRefs[5] = el"
              :device-id="device_currentId"
              :title="`${activeGatewayName}-${currentDeviceIndex} - ${$t('message.pre')}`"
              color="#facc14"
              :data="preArr"
              :x-axis-data="xaxisData1"
              unit="Kpa"
              :zoom-id="5"
              :is-zoomed="isZoomed && zoomedChartId === 5"
              @zoom="handleZoom"
              legend-name="压力（Kpa）"
            />
          </div>
        </div>
      </div>
    </div>
  </main>
  <!-- 设备统计抽屉 -->
  <el-drawer
    v-model="showDeviceStats"
    title="设备状态统计(根据数据判断在线情况)"
    direction="rtl"
    size="900px"
    :with-header="true"
  >
    <DeviceStatsCard :ws="wsInstance.value?.websocketInstance ?? null" />
  </el-drawer>
  
  <!-- 活跃报警对话框 -->
  <el-dialog
    v-model="showAlarmsDialog"
    title="活跃报警列表"
    width="800px"
    :close-on-click-modal="false"
  >
    <div class="alarms-container">
      <div class="alarms-header">
        <span>当前共有 {{ activeAlarms.length }} 个活跃报警</span>
        <el-button 
          v-if="activeAlarms.length > 0" 
          type="danger" 
          size="small" 
          @click="clearAllAlarms"
        >
          清除所有报警
        </el-button>
      </div>
      
      <div v-if="activeAlarms.length === 0" class="no-alarms">
        <el-icon style="font-size: 48px; color: #67c23a;"><SuccessFilled /></el-icon>
        <p>暂无活跃报警</p>
      </div>
      
      <div v-else class="alarms-list">
        <div 
          v-for="(alarm, index) in activeAlarms" 
          :key="`${alarm.deviceId}_${alarm.sensorIndex}`"
          class="alarm-item"
        >
          <div class="alarm-icon">
            <el-icon style="font-size: 24px; color: #ff4757;"><Warning /></el-icon>
          </div>
          <div class="alarm-content">
            <div class="alarm-title">{{ alarm.message }}</div>
            <div class="alarm-details">
              <span class="detail-item">设备: {{ alarm.deviceName || alarm.deviceId }}</span>
              <span class="detail-item">传感器: {{ alarm.sensorType }}</span>
              <span class="detail-item">状态值: {{ alarm.value }}</span>
              <span v-if="alarm.actualValue !== undefined" class="detail-item current-value">
                当前值: {{ alarm.actualValue }}
              </span>
              <span v-if="alarm.maxValue !== undefined && alarm.maxValue !== alarm.actualValue" class="detail-item max-value">
                最大值: <strong>{{ alarm.maxValue }}</strong>
              </span>
              <span v-if="alarm.alarmCount && alarm.alarmCount > 1" class="detail-item alarm-count">
                报警次数: <span class="count-badge">{{ alarm.alarmCount }}</span>
              </span>
              <span class="detail-item">首次时间: {{ new Date(alarm.timestamp).toLocaleString() }}</span>
              <span v-if="alarm.lastUpdateTime && alarm.lastUpdateTime !== alarm.timestamp" class="detail-item last-update">
                最新时间: {{ new Date(alarm.lastUpdateTime).toLocaleString() }}
              </span>
            </div>
          </div>
          <div class="alarm-actions">
            <el-button 
              type="primary" 
              size="small" 
              @click="clearSingleAlarm(alarm.deviceId, alarm.sensorIndex)"
            >
              清除
            </el-button>
          </div>
        </div>
      </div>
    </div>
    
    <template #footer>
      <div class="alarm-dialog-footer">
        <el-button @click="showAlarmsDialog = false">关闭</el-button>
        <el-button type="primary" @click="toggleVoiceAlarm">
          {{ alarmConfig.voiceEnabled ? '关闭' : '开启' }}语音报警
        </el-button>
      </div>
    </template>
  </el-dialog>
  <teleport to="body">
    <div
      v-if="contextMenuVisible"
      :style="contextMenuStyle"
      class="my-context-menu"
    >
      <div @click="toggleWebSocketPause">
        {{ isManuallyPaused ? '恢复接收' : '暂停接收' }}
      </div>
    </div>

  </teleport>

  <!-- 通道名称编辑器抽屉 -->
    <el-drawer
      :model-value="isChannelEditorOpen"
      title="通道名称管理"
      direction="ltr"
      size="500px"
      @close="admin_store.toggleChannelEditor(false)"
    >
      <ChannelNameEditor :alarmWorker="alarmWorker" />
    </el-drawer>
</template>

<script lang="ts" setup>
import { watch, ref, onMounted, reactive, onUnmounted, onActivated, onDeactivated, computed, nextTick } from 'vue'
import { moduleStore } from '../store/module'
import { storeToRefs } from 'pinia'
import { getCurrentInstance } from 'vue'
import { adminStore } from '@/store/admin'
import { alarmStore } from '@/store/alarm'
import ChannelNameEditor from '@/components/common/ChannelNameEditor.vue' // 导入抽屉组件
const admin_store = adminStore()
let { isChannelEditorOpen } = storeToRefs(admin_store) // 获取抽屉状态
let {isOpenDrawer} = storeToRefs(admin_store)
let {alarmConfig} = storeToRefs(alarmStore())
import CustomTitleBar from '../components/common/CustomTitleBar.vue'
import HomeHeader from '../components/common/Header.vue'
import SystemInfo from '../components/home/SystemInfo.vue'
import ChartSection from '../components/home/ChartSection.vue'
import ModuleSelector from '../components/home/ModuleSelector.vue'
import * as echarts from 'echarts'
import { historyTotal } from '../utils/chart'
import { ElMessage } from 'element-plus'
let {proxy}:any = getCurrentInstance()
let saveErrorInfoWorker: Worker | null = null;
import { WebsocketIo } from '../utils/websocket'
import indexDb from '../local/indexDb'
import { channelNameDb } from '../local/channelNameDb'
import CmdCenter from '../components/common/CmdCenter.vue'
import GatewayConfigDialog from '../components/common/GatewayConfigDialog.vue'
import { Operation, Warning, SuccessFilled } from '@element-plus/icons-vue'
import { gatewayStore } from '../store/gateway'
import { useServerStore } from '../store/server'
import DeviceStatsCard from '../components/DeviceStatsCard.vue'
import { userStore } from '@/store/user'
const user_store = userStore()
const module_store = moduleStore()
let {indexDbNum} = storeToRefs(user_store)
const gateway_store = gatewayStore()
const server_store = useServerStore()
const { gatewayList, activeGatewayId, currentIp } = storeToRefs(gateway_store)
const { current_num,pendingDevices } = storeToRefs(module_store)
// 计算当前激活的网关名称（带"网关"字样）
const activeGatewayName = computed(() => {
  const activeGateway = gatewayList.value.find(g => g.id === activeGatewayId.value)
  if (!activeGateway) return ''
  return activeGateway.name
})

// 计算当前监测点编号（只取数字）
const currentDeviceIndex = computed(() => {
  const current = module_store.selectModule.find(m => m.id === device_currentId.value)
  if (!current) return ''
  return current.deviceName
})

// Store refs
const { device_currentId } = storeToRefs(module_store)


// 初始化模块和设备的通用函数
const initializeModulesAndDevices = async (gatewayId: number, gatewayIp: string) => {
  try {
    console.log('=== 开始初始化模块列表 ===');
    console.log('网关ID:', gatewayId, '网关IP:', gatewayIp);
    
    // 检查参数有效性
    if (!gatewayId || !gatewayIp) {
      console.error('无效的网关参数:', { gatewayId, gatewayIp });
      return;
    }
    
    await module_store.getModuleList(gatewayId, gatewayIp);
    console.log('模块列表初始化完成:', module_store.selectModule.length, '个模块');
    
    // 模块列表加载完成后，初始化首个设备
    if (module_store.selectModule.length > 0) {
      const firstDeviceId = module_store.selectModule[0].id;
      console.log('初始化首个设备:', firstDeviceId);
      
      // 延迟一点时间确保其他组件也完成初始化
      setTimeout(() => {
        console.log('执行taggleDevice初始化设备数据');
        taggleDevice(firstDeviceId, false, false);
      }, 300); // 增加延迟时间从200ms到2300ms
    } else {
      console.warn('模块列表为空，无法初始化设备');
    }
    
    console.log('=== 模块初始化完成 ===');
  } catch (error) {
    console.error('初始化模块和设备失败:', error);
  }
};

// Data
const chartMaxLength = ref(10)
const isWindowFocused = ref(true)
const isWebSocketPaused = ref(false)
const isManuallyPaused = ref(false)
const isAutoPaused = ref(false)
const isZoomed = ref(false)
const zoomedChartId = ref(-1)

// 新增：失焦计时器和提示
const focusLostTimer = ref<any>(null)



// 添加防抖和性能优化
const updateChartDebounceTimer = ref<any>(null)
const lastUpdateTime = ref(0)
const UPDATE_INTERVAL = 100 // 最小更新间隔(ms)

// 性能优化：批量数组更新函数
const batchUpdateArrays = (updates: Array<{arr: any[], data: any[]}>) => {
  // 使用批量操作减少响应式系统的触发次数
  updates.forEach(({arr, data}) => {
    if (arr.length !== data.length) {
      arr.splice(0, arr.length, ...data)
    } else {
      // 如果长度相同，直接替换元素避免数组重新分配
      for (let i = 0; i < data.length; i++) {
        arr[i] = data[i]
      }
    }
  })
}

// Chart data
const uvcArr = reactive<number[]>([])
const infArr = reactive<number[]>([])
const temArr = reactive<number[]>([])
const humArr = reactive<number[]>([])
const preArr = reactive<number[]>([])

const xaxisData = reactive<string[]>([])
const xaxisData1 = reactive<string[]>([])
const xaxisData2 = reactive<string[]>([])

const history_bar = ref()
let barChart: echarts.ECharts | null = null

const wsInstance = ref<any>(null)

// ChartSection组件ref
const chartRefs = ref<{ [key: number]: any }>({})

const showCmdCenter = ref(false)
const showGatewayConfigDialog = ref(false)
const contextMenuVisible = ref(false)
const contextMenuStyle = ref({})
const showDeviceStats = ref(false)

const barChartData = ref([10, 22, 28, 43, 49]); // 默认实例数据
const barChartXAxis = ref(['2025-04-21', '2025-04-22', '2025-04-23', '2025-04-24', '2025-04-25']);
const barChartType = ref<number|null>(null); // null为实例数据，0-4为类型

// 优化防抖更新图表 - 增加频率限制和批量更新
const debouncedUpdateCharts = () => {
  const now = Date.now()
  
  // 频率限制：最小更新间隔100ms
  if (now - lastUpdateTime.value < UPDATE_INTERVAL) {
    if (updateChartDebounceTimer.value) {
      clearTimeout(updateChartDebounceTimer.value)
    }
    updateChartDebounceTimer.value = setTimeout(() => {
      updateAllCharts()
      lastUpdateTime.value = Date.now()
      updateChartDebounceTimer.value = null
    }, UPDATE_INTERVAL - (now - lastUpdateTime.value))
    return
  }
  
  // 立即更新
  updateAllCharts()
  lastUpdateTime.value = now
}

// 清理数组数据，防止内存泄漏
const cleanupArrays = () => {
  const maxLen = chartMaxLength.value
  if (uvcArr.length > maxLen) uvcArr.splice(0, uvcArr.length - maxLen)
  if (infArr.length > maxLen) infArr.splice(0, infArr.length - maxLen)
  if (temArr.length > maxLen) temArr.splice(0, temArr.length - maxLen)
  if (humArr.length > maxLen) humArr.splice(0, humArr.length - maxLen)
  if (preArr.length > maxLen) preArr.splice(0, preArr.length - maxLen)
  if (xaxisData.length > maxLen) xaxisData.splice(0, xaxisData.length - maxLen)
  if (xaxisData1.length > maxLen) xaxisData1.splice(0, xaxisData1.length - maxLen)
  if (xaxisData2.length > maxLen) xaxisData2.splice(0, xaxisData2.length - maxLen)
}

// 定期内存清理
let memoryCleanupTimer: any = null
const startMemoryCleanup = () => {
  memoryCleanupTimer = setInterval(() => {
    cleanupArrays()
    // 强制垃圾回收（如果可用）
    if (window.gc) {
      window.gc()
    }
  }, 30000) // 每30秒清理一次
}

const stopMemoryCleanup = () => {
  if (memoryCleanupTimer) {
    clearInterval(memoryCleanupTimer)
    memoryCleanupTimer = null
  }
}

// 性能监控
let performanceMonitorTimer: any = null
const startPerformanceMonitor = () => {
  performanceMonitorTimer = setInterval(() => {
    const memoryInfo = (performance as any).memory
    if (memoryInfo) {
      const usedMB = Math.round(memoryInfo.usedJSHeapSize / 1024 / 1024)
      const totalMB = Math.round(memoryInfo.totalJSHeapSize / 1024 / 1024)
      const limitMB = Math.round(memoryInfo.jsHeapSizeLimit / 1024 / 1024)
      
      // 如果内存使用超过80%，强制清理
      if (usedMB / limitMB > 0.9) {
        console.warn('内存使用过高，强制清理')
        cleanupArrays()
        if (window.gc) window.gc()
      }
    }
  }, 60000) // 每分钟检查一次
}

const stopPerformanceMonitor = () => {
  if (performanceMonitorTimer) {
    clearInterval(performanceMonitorTimer)
    performanceMonitorTimer = null
  }
}

// 切换网关
const handleGatewaySwitch = async (id: number) => {
  gateway_store.switchGateway(id)
  

  // 先设置为网关级别统计
  device_currentId.value = -1
  isGatewayLevelStats.value = true
  
  const selectedGateway = gateway_store.gatewayList.find(g => g.id === id)
  const gatewayIp = selectedGateway?.ip || ""
  // 重新连接WebSocket到新网关
  if (wsInstance.value) {
    
    // 设置当前网关IP到WebSocket实例（用于重连时自动订阅）
    wsInstance.value.setCurrentGatewayIp(gatewayIp)
    
    // 发送网关切换消息
    wsInstance.value.sendMessage(JSON.stringify({
      action: "taggleGateway",
      gatewayIp: gatewayIp
    }))
  }
  
  // 切换网关
  const customEvent = new CustomEvent('custom-event', {detail: { type: 'taggleGateway', data: JSON.stringify(module_store.onlineDevice) }});
  window.dispatchEvent(customEvent);

  // 获取新的网关名称
  module_store.getModuleList(id,currentIp.value)
  
  // 先显示网关级别的报警统计
  const defaultType = selectedLegend.value !== null ? selectedLegend.value : 4; // 默认使用紫外传感器统计
  await getAlarmStats(defaultType); // 网关级别统计
  
  // 如果之前没有选中图例，设置默认选中
  if (selectedLegend.value === null) {
    selectedLegend.value = defaultType;
  }

  // 优先切换到监测点1，如果不在线则切换到第一个在线的设备
  // 等待一下让模块列表更新
  try {
  setTimeout(async () => {
    // 检查当前网关下的在线设备
    const currentGatewayDevices = module_store.onlineDevice.filter((device: {gatewayIp: string, isOnline: boolean}) =>
      device.gatewayIp === gatewayIp && device.isOnline
    )
    
    if (currentGatewayDevices.length > 0) {
      // 优先检查监测点1是否在线
      const device1 = currentGatewayDevices.find((device: { deviceId: string | number }) => device.deviceId === '1' || device.deviceId === 1)
      
      if (device1) {
        // 监测点1在线，切换到监测点1
        await taggleDevice(1, false, true) // 不跳过报警统计更新
      } else {
        // 监测点1不在线，切换到第一个在线的设备
        const firstOnlineDevice = currentGatewayDevices.sort((a, b) => a.deviceId - b.deviceId)[0]

        const deviceId = parseInt(firstOnlineDevice.deviceId)
        await taggleDevice(deviceId, false, true) // 不跳过报警统计更新
      }
    } else {
      // 没有在线设备，默认切换到监测点1（即使离线）
      if (module_store.selectModule && module_store.selectModule.length > 0) {
        await taggleDevice(module_store.selectModule[0].id, false, true)
      }
    }
  }, 500) // 延迟500ms让用户看到网关统计后再切换到设备
  } catch (error) {
    console.error('Error fetching gateway devices:', error);
    await taggleDevice(1, false, false) // 不跳过报警统计更新
  }

  ElMessage({
    type: 'success',
    message: `已切换到网关 ${gateway_store.gatewayList.find(g => g.id === id)?.name || '未知'}`, 
    duration: 2000
  });
}

// 指令中心发送指令方法
async function sendCmd(cmd: string) {
  return new Promise<string>((resolve) => {
    if (!wsInstance.value || !wsInstance.value.websocketIsNormal()) {
      return resolve('WebSocket 未连接');
    }
    const responses: any[] = [];
    let timeoutId: any;
    
    const handler = (event: CustomEvent) => {
      const data = event.detail;
      console.log('Home: 收到WebSocket消息', data);
      
      // 检查是否是网关指令响应
      if (data.action === 'gatewayCommandResponse' || 
          (data.action === 'gateway_result' && data.type)) {
        console.log('Home: 匹配到指令响应', data);
        responses.push(data);
        // 每次收到响应都重置超时，保证能收集连续响应
        clearTimeout(timeoutId);
        timeoutId = setTimeout(() => {
          window.removeEventListener('websocket-message', handler as EventListener);
          resolve(JSON.stringify(responses));
        }, 1500); // 1.5秒内无新响应则判定收集完毕
      }
    };
    
    // 监听全局WebSocket消息事件
    window.addEventListener('websocket-message', handler as EventListener);
    wsInstance.value.sendMessage(cmd);
    
    // 最长等待5秒
    timeoutId = setTimeout(() => {
      window.removeEventListener('websocket-message', handler as EventListener);
      resolve(JSON.stringify(responses.length ? responses : '等待响应超时'));
    }, 5000);
  });
}

// 处理键盘事件
const handleKeyDown = (event: KeyboardEvent) => {
  // 只在 debug 模式下响应 Ctrl + H 快捷键
  if ((event.ctrlKey && event.key === 'h') && gateway_store.debug) {
    event.preventDefault()
    showGatewayConfigDialog.value = true
  }
}

// 统一的暂停状态管理
const updatePauseState = () => {
  isWebSocketPaused.value = isManuallyPaused.value || isAutoPaused.value
}

// 暂停/继续 WebSocket
const toggleWebSocketPause = () => {
  isManuallyPaused.value = !isManuallyPaused.value
  updatePauseState()
  hideContextMenu()
}



// 处理窗口可见性变化（使用 Electron IPC 通信）
const handleWindowVisibilityChange = (data: { visible: boolean, timeout?: boolean }) => {
  
  isWindowFocused.value = data.visible
  
  if (data.visible) {
    // 窗口可见，清除自动暂停
    if (focusLostTimer.value) {
      clearTimeout(focusLostTimer.value)
      focusLostTimer.value = null
      console.log('清除失焦定时器')
    }
    isAutoPaused.value = false
    updatePauseState() // 只有在非手动暂停时才恢复
    
    // 通知Worker退出节能模式
    if (sensorDataWorker.value) {
      (sensorDataWorker.value as Worker).postMessage({
        type: 'setThrottleMode',
        enabled: false
      });
    }
    
    // 恢复图表更新
    setTimeout(() => {
      updateAllCharts()
    },200)
    console.log('窗口恢复可见，自动暂停已清除')
  } else {
    // 窗口隐藏
    if (data.timeout) {
      // 这是超时后的暂停信号
      console.log('窗口隐藏超过1分钟，开始自动暂停')
      isAutoPaused.value = true
      updatePauseState()
      
      // 通知Worker进入节能模式
      if (sensorDataWorker.value) {
        (sensorDataWorker.value as Worker).postMessage({
          type: 'setThrottleMode',
          enabled: true
        });
      }
    } else {
      // 这是刚隐藏的信号，不立即暂停
      console.log('窗口隐藏，等待超时信号')
    }
  }
  
  console.log('处理后WebSocket暂停状态:', isWebSocketPaused.value)
}
const handleFlashFn = (onlineList: Record<string, any>[]) => { 
   const onlineModules = onlineList.filter(item => item.gatewayIp === currentIp.value)
    if (onlineModules.length > 0) {
      const customEvent = new CustomEvent('custom-event', {detail: { type: 'update', data: JSON.stringify(onlineModules) }});
      window.dispatchEvent(customEvent);
    }
}

const queryPendingDevices = async () => {
  const cmd = JSON.stringify({
    action: 'queryPendingDevices',
    gatewayIp: currentIp.value
  })
  const response = await sendCmd(cmd)
}
// 监听设备数量变化
watch(current_num,() => {
  // 再去调用一次
  module_store.getModuleList(activeGatewayId.value,currentIp.value)
})
// WebSocket 数据处理
const handleWebSocketMessage = (data: any) => {
  // 分发WebSocket消息给其他组件
  const websocketEvent = new CustomEvent('websocket-message', { detail: data })
  window.dispatchEvent(websocketEvent)

  // 只有手动暂停或者失焦超过1分钟才停止渲染
  if (isWebSocketPaused.value) return;
  // 监听设备掉线的情况
  if (data.action === 'deviceOffline') { 
    let gatewayIp: string = data.data.gatewayIp // 掉线的网关
    let deviceId: string = data.data.deviceId  // 掉线的设备ID
      const customEvent = new CustomEvent('custom-event', {detail: { type: 'deviceOffline', data: JSON.stringify({gatewayIp, deviceId}) }});
      window.dispatchEvent(customEvent);
      module_store.module_num = module_store.module_num - 1
      module_store.online_num = module_store.online_num - 1
  } 

  if (data.action === "deviceStatsUpdate") {
      module_store.onlineDevice = data.data.deviceDetails
       // 通知闪烁功能
      handleFlashFn(data.data.deviceDetails)
      module_store.module_num = data.data.totalDevices
      module_store.online_num = data.data.onlineDevices
   
  }
  // 检查是否包含设备状态数据，用于报警检测
  if (data && data.ID && data.sta && Array.isArray(data.sta)) {
    console.log('发送的数据', data)
    
    // 处理电量数据显示
    if (data.battery !== undefined && data.battery !== null) {
      // 更新设备电量信息到store或组件状态
      const deviceId = data.ID;
      const batteryLevel = parseFloat(data.battery);
      
      // 发送电量更新事件给ModuleSelector组件
      const batteryEvent = new CustomEvent('custom-event', {
        detail: { 
          type: 'batteryUpdate', 
          deviceId: deviceId,
          batteryLevel: batteryLevel,
          gatewayIp: data.gatewayIp
        }
      });
      window.dispatchEvent(batteryEvent);
      
      console.log(`设备 ${deviceId} 电量更新: ${batteryLevel}%`);
    }

    // 新增：处理信号强度数据显示
    if (data.signal !== undefined && data.signal !== null) {
        const convertSignalToSignalStrength = (signal: number): number => {
        if (signal > 0) return 5;
        if (signal >= -20) return 4;
        if (signal >= -39) return 3;
        if (signal >= -59) return 2;
        if (signal >= -80) return 1;
        return 0; // 非常弱
      };

      const deviceId = data.ID;
      const signal = parseFloat(data.signal);
      const signalStrength = convertSignalToSignalStrength(signal);

      const signalEvent = new CustomEvent('custom-event', {
        detail: {
          type: 'signalUpdate',
          deviceId: deviceId,
          signal: data.signal,
          signalStrength: signalStrength,
          gatewayIp: data.gatewayIp
        }
      });
      window.dispatchEvent(signalEvent);
    }
    
    // 发送设备状态数据到报警Worker进行报警检测
    if (alarmWorker.value && alarmConfig.value.enabled) {
      // 获取当前的设备名称映射并同步发送
      const sendDeviceStatusWithNames = async () => {
        try {
          const { channelNameDb } = await import('../local/channelNameDb')
          const deviceNameMap = await channelNameDb.getAllNames()
          const deviceNameMapObject = Object.fromEntries(deviceNameMap)
          alarmWorker!.value.postMessage({
            type: 'process_device_status',
            data: {
              ID: data.ID,
              data: data.data || [],
              sta: data.sta, // [温度, 湿度, 压力, 红外, 紫外]
              gatewayIp: data.gatewayIp,
              gatewayName: gateway_store.gatewayList.find(g => g.ip === data.gatewayIp)?.name || '未知网关',
              moduleNameMap: deviceNameMapObject // 添加设备名称映射
            }
          })
        } catch (error) {
          console.error('获取设备名称映射失败，使用默认处理:', error)
          // 如果获取失败，仍然发送基本数据
          alarmWorker.value.postMessage({
            type: 'process_device_status',
            data: {
              ID: data.ID,
              data: data.data || [],
              sta: data.sta,
              gatewayIp: data.gatewayIp,
              gatewayName: gateway_store.gatewayList.find(g => g.ip === data.gatewayIp)?.name || '未知网关'
            }
          })
        }
      }
      
      sendDeviceStatusWithNames()
    }
  }

  // 模块设备数量的更改
  if (data.action === "getModuleNum") {
    console.log('接收到获取设备的数据',data)
    // 网关设备数量
    let size: number = data.size 
    
    // 重新赋值设备数量
    module_store.setDevice(data.deviceList)

    // 判断这里获取到的数量是否大于10,如果大于10再赋值
    if (data.gateway_ip === currentIp.value) current_num.value = Math.max(size,10)

  }

  // 获取带入网的设备
  if (data.action === "pendingDevices") {
    console.log('🔍 [DEBUG] 收到pendingDevices消息:', data)
    console.log('🔍 [DEBUG] data.deviceList:', data.deviceList)
    console.log('🔍 [DEBUG] data.devices:', data.devices)
    console.log('🔍 [DEBUG] data.data:', data.data)
    
    // 尝试不同的字段名，并确保数据格式正确
    let deviceList = data.deviceList || data.devices || data.data || []
    console.log('🔍 [DEBUG] 原始deviceList:', deviceList)
    
    // 如果是字符串数组，转换为Device对象数组
    if (Array.isArray(deviceList) && deviceList.length > 0) {
      if (typeof deviceList[0] === 'string') {
        // 如果是字符串数组，转换为Device对象数组
        deviceList = deviceList.map(esn => ({
          esn: esn,
          deviceId: esn,
          status: true
        }))
        console.log('🔍 [DEBUG] 转换后的deviceList:', deviceList)
      }
    }
    
    console.log('🔍 [DEBUG] 最终使用的deviceList:', deviceList)
    module_store.setPendingDevices(deviceList as any[])
    console.log('🔍 [DEBUG] 设置后的pendingDevices:', module_store.pendingDevices)
  }
  
  // 不在主线程解析JSON，直接发送原始数据到Worker进行处理
  if (sensorDataWorker.value) {
    (sensorDataWorker.value as Worker).postMessage({
      type: 'process_websocket_data',
      rawData: JSON.stringify(data),
      deviceId: device_currentId.value,
      gatewayIp: currentIp.value,
      isZoomed: isZoomed.value,
      zoomedChartId: zoomedChartId.value
    });
  }
}

const handleZoom = (chartId: number) => {
  isZoomed.value = !isZoomed.value
  zoomedChartId.value = isZoomed.value ? chartId : -1
  chartMaxLength.value = isZoomed.value ? 300 : 10
  
  // 通知Worker缩放状态变化
  if (sensorDataWorker.value) {
    const sensorTypeMap: { [key: number]: string } = {
      1: 'uvc',
      2: 'inf', 
      3: 'tem',
      4: 'hum',
      5: 'pre'
    };
    
    (sensorDataWorker.value as Worker).postMessage({
      type: 'setZoomMode',
      isZoomed: isZoomed.value,
      zoomedSensor: isZoomed.value ? sensorTypeMap[chartId] : null
    });
  }
}

// 处理窗口大小变化
const handleWindowResize = () => {
  // 使用防抖避免频繁调用
  if (updateChartsTimer) {
    cancelAnimationFrame(updateChartsTimer);
  }
  
  updateChartsTimer = requestAnimationFrame(() => {
    // 重新调整history_bar图表（ECharts实例）
    if (barChart && typeof barChart.resize === 'function') {
      setTimeout(() => {
        barChart!.resize();
      }, 300);
    }
    
    // 重新调整所有图表大小
    const charts = Object.values(chartRefs.value);
    charts.forEach((chart) => {
      if (chart && typeof chart.resize === 'function') {
        chart.resize();
      }
      if (chart && typeof chart.updateChart === 'function') {
        chart.updateChart();
      }
    });
    updateChartsTimer = null;
  });
}

// 优化的图表更新函数 - 使用requestAnimationFrame和防抖提升性能
let updateChartsTimer: number | null = null;
const updateAllCharts = () => {
  // 使用防抖避免频繁更新
  if (updateChartsTimer) {
    cancelAnimationFrame(updateChartsTimer);
  }
  
  updateChartsTimer = requestAnimationFrame(() => {
    if (isZoomed.value) {
      // 放大模式下，只更新当前放大的图表
      const zoomedChart = chartRefs.value[zoomedChartId.value];
      if (zoomedChart && typeof zoomedChart.updateChart === 'function') {
        zoomedChart.updateChart();
      }
    } else {
      // 正常模式下，批量更新所有图表
      const charts = Object.values(chartRefs.value);
      charts.forEach((chart) => {
        if (chart && typeof chart.updateChart === 'function') {
          chart.updateChart();
        }
      });
    }
    updateChartsTimer = null;
  });
}

const initDeviceData = async (id: number) => { 
  // 调用接口获取初始化数据
  try {
    const res = await proxy.$adminHttp.get('/admin/getInitialData', {
      params: {
        gateway_ip: currentIp.value,
        module_id: id
      }
    });

    if (res.data.code === 200 && res.data.data && res.data.data.normalData) {
      // 将获取到的数据发送给Worker进行处理
      if (sensorDataWorker.value) {
        (sensorDataWorker.value as Worker).postMessage({
          type: 'process_initial_data',
          initialData: res.data.data.normalData
        });
      }
    }
  } catch (error) {
    console.error('获取初始化数据失败:', error);
  }
}
const taggleDevice = async (id: number, showMsg = true, skipAlarmStats = false) => {
  device_currentId.value = id

  // 更新模块选中状态
  module_store.selectModule.forEach(module => {
    module.isChecked = module.id === id
  })

  // 清空所有数据数组
  uvcArr.length = 0
  infArr.length = 0
  temArr.length = 0
  humArr.length = 0
  preArr.length = 0
  xaxisData.length = 0
  xaxisData1.length = 0
  xaxisData2.length = 0

  // 通知Worker重置数据缓冲区
  if (sensorDataWorker.value) {
    (sensorDataWorker.value as Worker).postMessage({ type: 'reset' });
  }

  await initDeviceData(id)

  // 立即刷新所有曲线和图例，确保图表显示为空状态
    setTimeout(() => {
      updateAllCharts();
    }, 10);
  

  // 只有在不跳过报警统计时才调用
  if (!skipAlarmStats) {
    // 切换监测点后，更新报警统计为监测点级别统计
    const defaultType = selectedLegend.value !== null ? selectedLegend.value : 4; // 默认使用紫外传感器统计
    await getAlarmStats(defaultType); // false表示监测点级别统计
    
    // 如果之前没有选中图例，设置默认选中
    if (selectedLegend.value === null) {
      selectedLegend.value = defaultType;
    }
  }


  // 显示切换提示
  if (showMsg) {
    const currentModule = module_store.selectModule.find(m => m.id === id);
    ElMessage({
      type: 'success',
      message: `已切换到${currentModule?.deviceName || '未知'}监测点位`,
      duration: 2000
    });
  }
}
function showContextMenu(e: MouseEvent) {
  e.preventDefault()
  contextMenuVisible.value = true
  contextMenuStyle.value = {
    position: 'fixed',
    left: e.clientX + 'px',
    top: e.clientY + 'px',
    zIndex: 9999
  }
  document.addEventListener('click', hideContextMenu)
}
function hideContextMenu() {
  contextMenuVisible.value = false
  document.removeEventListener('click', hideContextMenu)
}

// Lifecycle
let gatewayListTimer: any = null

// 首次获取失败自动重试
const fetchGatewayListWithRetry = async (retryInterval = 3000, maxRetries = 10) => {
  let success = false
  let attemptCount = 0
  
  while (!success && attemptCount < maxRetries) {
    try {
      console.log(`尝试获取网关列表... (第${attemptCount + 1}次/共${maxRetries}次)`);
      await gateway_store.fetchGatewayList()
      if (gateway_store.gatewayList.length > 0) {
        console.log('网关列表获取成功:', gateway_store.gatewayList);
        success = true
      } else {
        console.warn('网关列表为空，将重试...');
        attemptCount++
        if (attemptCount < maxRetries) {
          await new Promise(res => setTimeout(res, retryInterval))
        }
      }
    } catch (e) {
      console.error('获取网关列表失败:', e);
      attemptCount++
      if (attemptCount < maxRetries) {
        await new Promise(res => setTimeout(res, retryInterval))
      }
    }
  }
  
  if (!success) {
    console.error(`经过${maxRetries}次尝试仍无法获取网关列表`);
    throw new Error('网关列表获取失败');
  }
}
   // 等待端口信息获取完成后再初始化WebSocket
  const initWebSocketWithRetry = async () => {
    let retryCount = 0
    const maxRetries = 20 // 最多重试20次（10秒）
    console.log('等待端口信息获取...')
    while (retryCount < maxRetries) {
      // 检查端口信息是否已获取
      if (server_store.ports.websocketPort > 0) {
        console.log('端口信息已获取，开始初始化WebSocket')
        console.log('当前端口配置:', server_store.ports)
        break
      }
      
      console.log(`等待端口信息获取... (${retryCount + 1}/${maxRetries})`)
      await new Promise(resolve => setTimeout(resolve, 500))
      retryCount++
    }
    
    if (server_store.ports.websocketPort === 0) {
      console.error('端口信息获取超时，跳过WebSocket连接')
      return
    }
    
    wsInstance.value = WebsocketIo.getInstance()
    console.log('WebSocket实例获取完成')
    
    // 连接到当前选中的网关
    if (gatewayList.value.length === 0) {
      console.warn('网关列表为空，跳过WebSocket连接')
      return
    }
    
    const currentGateway = gateway_store.gatewayList.find(g => g.id === gateway_store.activeGatewayId)
    
    if (currentGateway) {
      // 设置当前网关IP到WebSocket实例
      console.log('设置网关IP到WebSocket实例:', currentGateway.ip)
      wsInstance.value.setCurrentGatewayIp(currentGateway.ip)
      
      const isWebSocketNormal = wsInstance.value.websocketIsNormal()
      console.log('WebSocket当前状态正常:', isWebSocketNormal)
      
      if (!isWebSocketNormal) {
        const websocketBaseUrl = server_store.getApiBaseUrl('websocket')
        console.log('WebSocket基础URL:', websocketBaseUrl)
        const websocketUrl = `ws://${websocketBaseUrl}`;
        console.log('准备连接WebSocket URL:', websocketUrl);
        
        if (!websocketBaseUrl || websocketBaseUrl === 'undefined:undefined') {
          console.error('WebSocket URL无效，端口信息可能未正确设置')
          console.log('当前端口配置:', server_store.ports)
          return
        }
        
        console.log('调用WebSocket连接...')
        wsInstance.value.connectWebsocket(websocketUrl)
        console.log('WebSocket连接调用完成')
      } else {
        console.log('WebSocket已连接，直接发送网关订阅')
        // 如果WebSocket已连接，直接发送网关订阅
        wsInstance.value.sendMessage(JSON.stringify({
          action: "taggleGateway",
          gatewayIp: currentGateway.ip
        }))
      }
    } else {
      console.warn('未找到当前网关信息')
    }
  }


onMounted(async () => {
  await indexDb.openDb('list') // 打开本地数据库存储
  
  // 先尝试获取网关列表
  try {
    console.log('开始获取网关列表...');
    await fetchGatewayListWithRetry();
    console.log('网关列表获取完成:', gateway_store.gatewayList);
    
    // 网关列表获取成功后，立即初始化模块
    if (gateway_store.activeGatewayId && gateway_store.currentIp) {
      console.log('网关信息可用，立即初始化模块列表');
      console.log('当前网关ID:', gateway_store.activeGatewayId, 'IP:', gateway_store.currentIp);
      await initializeModulesAndDevices(gateway_store.activeGatewayId, gateway_store.currentIp);
    } else {
      console.warn('网关列表获取后仍无可用网关信息');
    }
    // 获取待入网的设备
    queryPendingDevices()
  } catch (error) {
    console.error('初始化网关列表失败:', error);
    // 即使网关列表获取失败，也要尝试使用现有信息初始化
    if (gateway_store.activeGatewayId && gateway_store.currentIp) {
      console.log('使用现有网关信息进行初始化');
      await initializeModulesAndDevices(gateway_store.activeGatewayId, gateway_store.currentIp);
    }
  }
  
  // 增加一个后备检查，确保模块被初始化
  setTimeout(() => {
    if (gateway_store.activeGatewayId && gateway_store.currentIp && module_store.selectModule.length === 0) {
      console.log('后备检查: 模块列表仍为空，再次尝试初始化');
      initializeModulesAndDevices(gateway_store.activeGatewayId, gateway_store.currentIp);
    }
  }, 2000); // 2秒后检查
  // 等待动态端口加载完成后再调用相关接口
  const waitForPortsAndInitialize = async () => {
    let retryCount = 0
    const maxRetries = 20 // 最多重试20次（10秒）
    console.log('等待端口信息获取完成...')
    
    while (retryCount < maxRetries) {
      // 检查端口信息是否已获取
      if (server_store.ports.websocketPort > 0) {
        console.log('端口信息已获取，开始调用相关接口')
        console.log('当前端口配置:', server_store.ports)
        
        // 获取系统的模式
        try {
          let isSuccess: boolean = await gateway_store.fetchDebugMode()
          if (isSuccess) break
          console.log('系统模式获取成功')
        } catch (error) {
          console.error('获取系统模式失败:', error)
        }
      }
      
      console.log(`等待端口信息获取... (${retryCount + 1}/${maxRetries})`)
      await new Promise(resolve => setTimeout(resolve, 500))
      retryCount++
    }
    
    if (server_store.ports.websocketPort === 0) {
      console.error('端口信息获取超时，跳过接口调用')
    }
  }
  
  // 异步等待端口信息并初始化相关接口
  waitForPortsAndInitialize()
  
  // 异步初始化WebSocket
  setTimeout(() => {
    initWebSocketWithRetry().then(() => {
      if (wsInstance.value) {
        console.log('设置全局WebSocket消息处理器');
        wsInstance.value.setGlobalHandler(handleWebSocketMessage);
        console.log('=== Home.vue onMounted WebSocket初始化完成 ===');
      }
    }).catch(error => {
      console.error('WebSocket初始化失败:', error);
    });
  }, 1000);

  // 确保 DOM 已渲染后再初始化 ECharts
  await nextTick()
  if (history_bar.value) {
    barChart = echarts.init(history_bar.value)
    barChart.setOption({
      grid: { left: 40, right: 20, top: 60, bottom: 40, containLabel: true },
      xAxis: {
        type: 'category',
        data: barChartXAxis.value,
        axisLabel: { color: '#b0c4de', fontSize: 16, fontWeight: 'bold' },
        axisLine: { lineStyle: { color: '#3a4a6b' } }
      },
      yAxis: {
        type: 'value',
        axisLabel: { color: '#b0c4de', fontSize: 16 },
        splitLine: { lineStyle: { color: '#2c3652' } },
        axisLine: { show: false }
      },
      series: [{
        data: barChartData.value,
        type: 'bar',
        barWidth: '40%',
        itemStyle: {
          borderRadius: [8, 8, 0, 0],
          color: {
            type: 'linear',
            x: 0, y: 0, x2: 0, y2: 1,
            colorStops: [
              { offset: 0, color: '#5b8ff9' },
              { offset: 1, color: '#3a4a6b' }
            ]
          },
          shadowColor: 'rgba(91,143,249,0.3)',
          shadowBlur: 10
        },
        emphasis: {
          itemStyle: {
            color: '#ffb761',
            borderColor: '#fff',
            borderWidth: 2
          }
        },
        label: {
          show: true,
          position: 'top',
          color: '#fff',
          fontWeight: 'bold',
          fontSize: 16
        }
      }],
      tooltip: {
        trigger: 'axis',
        axisPointer: { type: 'shadow' },
        backgroundColor: '#222',
        borderColor: '#5b8ff9',
        borderWidth: 1,
        textStyle: { color: '#fff', fontSize: 14 }
      }
    })
    
    // 初始化完成后，如果有默认选中的图例，获取对应的统计数据
    if (selectedLegend.value !== null) {
      await getAlarmStats(selectedLegend.value);
    }
  }

  // 监听窗口变化并调整图表大小
  window.addEventListener('contextmenu', showContextMenu)
  
  // 添加键盘事件监听器
  window.addEventListener('keydown', handleKeyDown)
  
  // 启动内存清理和性能监控
  startMemoryCleanup()
  startPerformanceMonitor()

     // 重新调整所有图表大小
  const charts = Object.values(chartRefs.value);
  setTimeout(() => {
    charts.forEach((chart) => {
      if (chart && typeof chart.resize === 'function') {
        chart.resize();
      }
      if (chart && typeof chart.updateChart === 'function') {
        chart.updateChart();
      }
    });
  }, 300);
  

  if (window.electronAPI && window.electronAPI.onWindowVisibilityChange) {
    window.electronAPI.onWindowVisibilityChange(handleWindowVisibilityChange)
  } else {
    console.warn('Electron API 不可用，可能在浏览器环境中运行')
  }
  // 初始化获取数据
  if (device_currentId.value) {
    initDeviceData(device_currentId.value);
  }
})

onUnmounted(() => {
  window.removeEventListener('contextmenu', showContextMenu)
  
  // 移除键盘事件监听器
  window.removeEventListener('keydown', handleKeyDown)
  
  // 清理防抖定时器
  if (updateChartDebounceTimer.value) {
    clearTimeout(updateChartDebounceTimer.value)
    updateChartDebounceTimer.value = null
  }
  
  // 清理图表实例
  Object.values(chartRefs.value).forEach((chart) => {
    if (chart && typeof chart.dispose === 'function') {
      chart.dispose()
    }
  })
  
  // 清理barChart实例
  if (barChart) {
    barChart.dispose()
    barChart = null
  }
  
  // 停止内存清理和性能监控
  stopMemoryCleanup()
  stopPerformanceMonitor()

  // 移除 Electron IPC 监听
  if (window.electronAPI && window.electronAPI.removeWindowVisibilityListener) {
    window.electronAPI.removeWindowVisibilityListener(handleWindowVisibilityChange)
    console.log('Electron IPC 监听器已移除')
  }

  // 清理Worker资源
  if (sensorDataWorker.value) {
    (sensorDataWorker.value as Worker).postMessage({ type: 'terminate' });
    sensorDataWorker.value = null
  }
  // uvDataWorker已移除
  if (alarmWorker.value) {
    alarmWorker.value.terminate()
    alarmWorker.value = null
  }
  
  // 停止语音播报
  if (speechSynthesis.value) {
    speechSynthesis.value.cancel()
  }
  
  // 停止心跳检测和恢复定时器
  stopWorkerHeartbeat();
  if (workerRecoveryTimer.value) {
    clearTimeout(workerRecoveryTimer.value);
    workerRecoveryTimer.value = null;
  }
  if (gatewayListTimer) clearInterval(gatewayListTimer)
})

onActivated(async () => {

  setTimeout(() => {
    initDeviceData(device_currentId.value);
  }, 300);
  // 重新初始化Worker
  if (!sensorDataWorker.value) {
    await initWorker();
  }

  // 重新获取待入网的设备
  queryPendingDevices()
  
  // 重新初始化报警Worker
  if (!alarmWorker.value) {
    await initAlarmWorker();
  }
  
  // 重新启动内存清理和性能监控
  startMemoryCleanup();
  startPerformanceMonitor();
  
  window.addEventListener('resize', handleWindowResize);
  window.addEventListener('contextmenu', showContextMenu);
  

  // 初始化 WebSocket 连接（等待端口信息）
  const initWebSocketOnActivated = async () => {
    console.log('开始初始化WebSocket连接...')
    
    // 检查端口信息是否可用
    if (server_store.ports.websocketPort === 0) {
      console.log('端口信息尚未获取，等待端口信息...')
      let retryCount = 0
      const maxRetries = 10 // 最多重试10次（5秒）
      
      while (retryCount < maxRetries && server_store.ports.websocketPort === 0) {
        await new Promise(resolve => setTimeout(resolve, 500))
        retryCount++
      }
      
      if (server_store.ports.websocketPort === 0) {
        console.error('端口信息获取超时，跳过WebSocket连接')
        return
      }
    }
    
    wsInstance.value = WebsocketIo.getInstance()
    console.log('WebSocket实例获取完成')
    
    const currentGateway = gateway_store.gatewayList.find(g => g.id === gateway_store.activeGatewayId)
    console.log('当前网关信息:', currentGateway)
    
    if (currentGateway) {
      // 设置当前网关IP到WebSocket实例
      console.log('设置网关IP到WebSocket实例:', currentGateway.ip)
      wsInstance.value.setCurrentGatewayIp(currentGateway.ip)
      
      const isWebSocketNormal = wsInstance.value.websocketIsNormal()
      console.log('WebSocket当前状态正常:', isWebSocketNormal)
      
      if (!isWebSocketNormal) {
        const websocketBaseUrl = server_store.getApiBaseUrl('websocket')
        console.log('WebSocket基础URL:', websocketBaseUrl)
        const websocketUrl = `ws://${websocketBaseUrl}`;
        console.log('准备连接WebSocket URL:', websocketUrl);
        
        if (!websocketBaseUrl || websocketBaseUrl === 'undefined:undefined') {
          console.error('WebSocket URL无效，端口信息可能未正确设置')
          console.log('当前端口配置:', server_store.ports)
          return
        }
        
        console.log('调用WebSocket连接...')
        wsInstance.value.connectWebsocket(websocketUrl)
        console.log('WebSocket连接调用完成')
      } else {
        console.log('WebSocket已连接，直接发送网关订阅')
        // 如果WebSocket已连接，直接发送网关订阅
        wsInstance.value.sendMessage(JSON.stringify({
          action: "taggleGateway",
          gatewayIp: currentGateway.ip
        }))
      }
    } else {
      console.warn('未找到当前网关信息')
    }
  }
  
  setTimeout(() => {
    // 异步初始化WebSocket
     initWebSocketOnActivated().then(() => {
       if (wsInstance.value) {
         // 在 onActivated 中，我们只需确保全局处理器被设置即可
         // 因为 WebsocketIo 实例是持久的
         wsInstance.value.setGlobalHandler(handleWebSocketMessage);
         console.log('=== Home.vue onActivated WebSocket初始化完成 ===');
       }
     }).catch(error => {
       console.error('onActivated WebSocket初始化失败:', error);
     });
  }, 1000);
  
  // 重新添加 Electron IPC 监听
  if (window.electronAPI && window.electronAPI.onWindowVisibilityChange) {
    window.electronAPI.onWindowVisibilityChange(handleWindowVisibilityChange)
  }
  
  // 重新初始化barChart
  await nextTick()
  if (history_bar.value && !barChart) {
    barChart = echarts.init(history_bar.value)
    barChart.setOption({
      grid: { left: 40, right: 20, top: 60, bottom: 40, containLabel: true },
      xAxis: {
        type: 'category',
        data: barChartXAxis.value,
        axisLabel: { color: '#b0c4de', fontSize: 16, fontWeight: 'bold' },
        axisLine: { lineStyle: { color: '#3a4a6b' } }
      },
      yAxis: {
        type: 'value',
        axisLabel: { color: '#b0c4de', fontSize: 16 },
        splitLine: { lineStyle: { color: '#2c3652' } },
        axisLine: { show: false }
      },
      series: [{
        data: barChartData.value,
        type: 'bar',
        barWidth: '40%',
        itemStyle: {
          borderRadius: [8, 8, 0, 0],
          color: {
            type: 'linear',
            x: 0, y: 0, x2: 0, y2: 1,
            colorStops: [
              { offset: 0, color: '#5b8ff9' },
              { offset: 1, color: '#3a4a6b' }
            ]
          },
          shadowColor: 'rgba(91,143,249,0.3)',
          shadowBlur: 10
        },
        emphasis: {
          itemStyle: {
            color: '#ffb761',
            borderColor: '#fff',
            borderWidth: 2
          }
        },
        label: {
          show: true,
          position: 'top',
          color: '#fff',
          fontWeight: 'bold',
          fontSize: 16
        }
      }],
      tooltip: {
        trigger: 'axis',
        axisPointer: { type: 'shadow' },
        backgroundColor: '#222',
        borderColor: '#5b8ff9',
        borderWidth: 1,
        textStyle: { color: '#fff', fontSize: 14 }
      }
    })
  }
})

onDeactivated(() => {
  // 移除事件监听器
  window.removeEventListener('resize', handleWindowResize);
  window.removeEventListener('contextmenu', showContextMenu);
  
  // 停止内存清理和性能监控
  stopMemoryCleanup();
  stopPerformanceMonitor();
  
  // 移除 Electron IPC 监听
  if (window.electronAPI && window.electronAPI.removeWindowVisibilityListener) {
    window.electronAPI.removeWindowVisibilityListener(handleWindowVisibilityChange)
  }
  
  // 停止语音播报
  if (speechSynthesis.value) {
    speechSynthesis.value.cancel();
  }
  
  // 停止心跳检测
  // stopWorkerHeartbeat();
  
  // 清理图表实例
  Object.values(chartRefs.value).forEach((chart) => {
    if (chart && typeof chart.dispose === 'function') {
      chart.dispose()
    }
  })

})

// 创建综合传感器数据处理Worker
const sensorDataWorker = ref<Worker | null>(null)
const workerHeartbeatTimer = ref<any>(null);
const workerRecoveryTimer = ref<any>(null);
const workerLastHeartbeat = ref<number>(Date.now());
const workerRecoveryAttempts = ref(0);

// 报警处理Worker
const alarmWorker = ref<Worker | null>(null);

const activeAlarms = ref<any[]>([])
const speechSynthesis = ref<SpeechSynthesis | null>(null)
const showAlarmsDialog = ref(false)

// 显示活跃报警对话框
const showActiveAlarms = () => {
  showAlarmsDialog.value = true
}

// 清除单个报警
const clearSingleAlarm = (deviceId: string, sensorIndex: number) => {
  if (alarmWorker.value) {
    // 发送清除单个报警的消息，包含网关IP信息
    const alarm = activeAlarms.value.find(
      (alarm) => alarm.deviceId === deviceId && alarm.sensorIndex === sensorIndex
    );
    
    alarmWorker.value.postMessage({
      type: 'clear_single_alarm',
      data: { 
        deviceId, 
        sensorIndex,
        gatewayIp: alarm?.gatewayIp || currentIp.value
      }
    });
  }
  
  // 从本地活跃报警列表中移除
  const index = activeAlarms.value.findIndex(alarm => 
    alarm.deviceId === deviceId && alarm.sensorIndex === sensorIndex
  )
  if (index !== -1) {
    activeAlarms.value.splice(index, 1)
  }
}
const initWorker = async () => {
  // 初始化综合传感器数据处理Worker
  if (typeof Worker !== 'undefined') {
    sensorDataWorker.value = new Worker(new URL('../worker/sensorDataWorker', import.meta.url))
    
    sensorDataWorker.value.onmessage = (e) => {
      const { type } = e.data;
      if (type === 'worker-error') {
        console.error('Worker报告错误:', e.data.error);
        scheduleWorkerRecovery();
        return;
      }
      
      if (type === 'heartbeat-reply') {
        workerLastHeartbeat.value = Date.now();
        workerRecoveryAttempts.value = 0;
        return;
      }
      
      if (type === 'device_flash') {
        // 处理设备闪烁事件
        const customEvent = new CustomEvent('custom-event', {
          detail: { type: 'flash', ID: e.data.deviceId }
        });
        window.dispatchEvent(customEvent);
        return;
      }

      if (type === 'repeateConnect') {
        gateway_store.refreshGatewayList(e.data.data)
        if (e.data.data.length === 0) {
          // 说明所有网关列表都掉线了
          const customEvent = new CustomEvent('custom-event', {
          detail: { type: 'reset'}
        });
        window.dispatchEvent(customEvent);
        }
      }
      // 使用requestAnimationFrame优化图表更新
      window.requestAnimationFrame(() => {
        handleWorkerChartUpdate(e.data);
      });
    };


    
    // Worker初始化完成
    
    // 配置Worker参数
    sensorDataWorker.value.postMessage({
      type: 'updateConfig',
      maxLength: 10,
      maxLengthZoomed: 300
    });
  }
  
  // 初始化报警处理Worker
  await initAlarmWorker();
  
  // 启动心跳检测
  startWorkerHeartbeat();

  // 初始化报警信息保存 Worker（全局唯一）
  if (typeof Worker !== 'undefined' && !saveErrorInfoWorker) {
    saveErrorInfoWorker = new Worker(new URL('../worker/saveErrorMessage', import.meta.url));

    // 发送动态端口信息给worker
    saveErrorInfoWorker.postMessage({
      type: 'set_port',
      host: server_store.getApiBaseUrl('admin'),
    });
  }
}

// 处理Worker图表更新的函数
const handleWorkerChartUpdate = (data: any) => {
  const { type } = data;
  switch (type) {
    case 'chart_update':
      // 单个图表更新
      const { chartId, sensorType, data: chartData, time } = data;
      
      // 优化：直接更新对应的数组，避免通用函数的开销
        if (sensorType === 'uvc') {
          Object.assign(uvcArr, chartData)
          Object.assign(xaxisData, time)
          uvcArr.length = chartData.length
          xaxisData.length = time.length
        } else if (sensorType === 'tem') {
          Object.assign(temArr, chartData)
          Object.assign(xaxisData2, time)
          temArr.length = chartData.length
          xaxisData2.length = time.length
        } else if (sensorType === 'hum') {
          Object.assign(humArr, chartData)
          Object.assign(xaxisData2, time)
          humArr.length = chartData.length
          xaxisData2.length = time.length
        } else if (sensorType === 'pre') {
          Object.assign(preArr, chartData)
          Object.assign(xaxisData1, time)
          preArr.length = chartData.length
          xaxisData1.length = time.length
        } else if (sensorType === 'inf') {
          Object.assign(infArr, chartData)
          Object.assign(xaxisData1, time)
          infArr.length = chartData.length
          xaxisData1.length = time.length
        }
      
      // 只更新指定的图表，避免全局更新
      const chartRef = chartRefs.value[chartId];
      if (chartRef && typeof chartRef.updateChart === 'function') {
        // 使用requestAnimationFrame确保流畅更新
        requestAnimationFrame(() => {
          chartRef.updateChart();
        });
      } else {
        console.error(`Chart ref ${chartId} not found or updateChart method missing`);
      }
      break;
      
    case 'chart_update_frame':
      // 逐帧图表更新（专用于紫外放大模式）
      const { chartId: frameChartId, sensorType: frameSensorType, data: frameChartData, time: frameTime, isFrameUpdate } = data;
      
      if (frameSensorType === 'uvc' && isFrameUpdate && frameChartData.length > 0) {
        // 高效的逐点追加：直接push新数据点，避免数组重新分配
        uvcArr.push(frameChartData[0]);
        xaxisData.push(frameTime[0]);
        // 保持数组长度在合理范围内（放大模式最多300个点）
        if (uvcArr.length > 300) {
          uvcArr.splice(0,10);
          xaxisData.splice(0,10);
        }
        
        // 使用逐帧渲染更新图表
        const frameChartRef = chartRefs.value[frameChartId];
        if (frameChartRef && typeof frameChartRef.updateChart === 'function') {
          frameChartRef.updateChart();
        }
      }
      break;
      
    case 'all_charts_update':
      // 所有图表更新
      const { data: allData, timeFormatted } = data;
      
      // 更新所有传感器数据
      uvcArr.splice(0, uvcArr.length, ...allData.uvc.data);
      temArr.splice(0, temArr.length, ...allData.tem.data);
      humArr.splice(0, humArr.length, ...allData.hum.data);
      preArr.splice(0, preArr.length, ...allData.pre.data);
      infArr.splice(0, infArr.length, ...allData.inf.data);
      
      // 更新时间轴
      xaxisData.splice(0, xaxisData.length, ...timeFormatted.uvc);
      xaxisData1.splice(0, xaxisData1.length, ...timeFormatted.inf);
      xaxisData2.splice(0, xaxisData2.length, ...timeFormatted.tem);
      
      // 更新所有图表
      debouncedUpdateCharts();
      break;
      
    case 'all_charts_update_batch':
      // 批量更新所有图表（高性能版本）
      const { data: batchData, timeFormatted: batchTimeFormatted } = data;
      // 优化：直接替换数组内容，减少响应式触发
      Object.assign(uvcArr, batchData.uvc.data);
      Object.assign(temArr, batchData.tem.data);
      Object.assign(humArr, batchData.hum.data);
      Object.assign(preArr, batchData.pre.data);
      Object.assign(infArr, batchData.inf.data);
      Object.assign(xaxisData, batchTimeFormatted.uvc);
      Object.assign(xaxisData1, batchTimeFormatted.inf);
      Object.assign(xaxisData2, batchTimeFormatted.tem);
      
      // 调整数组长度
      uvcArr.length = batchData.uvc.data.length;
      temArr.length = batchData.tem.data.length;
      humArr.length = batchData.hum.data.length;
      preArr.length = batchData.pre.data.length;
      infArr.length = batchData.inf.data.length;
      xaxisData.length = batchTimeFormatted.uvc.length;
      xaxisData1.length = batchTimeFormatted.inf.length;
      xaxisData2.length = batchTimeFormatted.tem.length;
      
      // 使用防抖批量更新所有图表，避免多次重绘
      debouncedUpdateCharts();
      break;
      
    case 'other_charts_update':
      // 其他传感器图表更新（除紫外线外）
      const { data: otherData, timeFormatted: otherTimeFormatted } = data;
      
      temArr.splice(0, temArr.length, ...otherData.tem.data);
      humArr.splice(0, humArr.length, ...otherData.hum.data);
      preArr.splice(0, preArr.length, ...otherData.pre.data);
      infArr.splice(0, infArr.length, ...otherData.inf.data);
      
      xaxisData1.splice(0, xaxisData1.length, ...otherTimeFormatted.inf);
      xaxisData2.splice(0, xaxisData2.length, ...otherTimeFormatted.tem);
      
      // 更新除紫外线外的图表
      chartRefs.value[2]?.updateChart(); // 红外
      chartRefs.value[3]?.updateChart(); // 温度
      chartRefs.value[4]?.updateChart(); // 湿度
      chartRefs.value[5]?.updateChart(); // 压力
      break;
  }
}

// 优化的传感器数据更新函数 - 减少数组操作开销
const updateSensorData = (sensorType: string, data: number[], time: string[]) => {
  // 使用Map提高查找效率
  const sensorMap: Record<string, { dataArr: typeof uvcArr, timeArr: typeof xaxisData }> = {
    'uvc': { dataArr: uvcArr, timeArr: xaxisData },
    'tem': { dataArr: temArr, timeArr: xaxisData2 },
    'hum': { dataArr: humArr, timeArr: xaxisData2 },
    'pre': { dataArr: preArr, timeArr: xaxisData2 },
    'inf': { dataArr: infArr, timeArr: xaxisData1 }
  };
  
  const sensor = sensorMap[sensorType];
  if (sensor) {
    // 使用批量更新函数提升性能
    batchUpdateArrays([
      { arr: sensor.dataArr, data },
      { arr: sensor.timeArr, data: time }
    ]);
  }
}

// 调用Worker恢复
const scheduleWorkerRecovery = () => {
  workerRecoveryAttempts.value++;
  // 指数退避策略：1s, 2s, 4s, 8s...
  const delay = Math.min(1000 * Math.pow(2, workerRecoveryAttempts.value - 1), 30000);
  if (workerRecoveryTimer.value) {
    clearTimeout(workerRecoveryTimer.value);
  }
  workerRecoveryTimer.value = setTimeout(() => {
    console.log('正在恢复Worker...');
    // 终止旧的Worker
    if (sensorDataWorker.value) {
      (sensorDataWorker.value as Worker).postMessage({ type: 'terminate' });
      sensorDataWorker.value = null
    }
    initWorker();
    // 恢复数据状态
    if (sensorDataWorker.value) {
      (sensorDataWorker.value as Worker).postMessage({ type: 'reset' });
    }
    // 更新所有图表
    updateAllCharts();
  }, delay);
};
// 初始化报警Worker
const initAlarmWorker = async () => {
  // 存在不需要再初始化了
  if (alarmWorker.value) return
  if (typeof Worker !== 'undefined') {
    alarmWorker.value = new Worker(new URL('../worker/alarmWorker', import.meta.url))
    
    // 初始化时同步设备名称映射
    try {
      const { channelNameDb } = await import('../local/channelNameDb')
      const deviceNameMap = await channelNameDb.getAllNames()
      const deviceNameMapObject = Object.fromEntries(deviceNameMap)
      alarmWorker.value.postMessage({
        type: 'update_device_names',
        data: {
          payload: deviceNameMapObject
        }
      })
    } catch (error) {
      console.error('同步设备名称映射失败:', error)
    }
    alarmWorker.value.onmessage = async (e) => {
      const { type, data, message } = e.data;
      
      switch (type) {
        case 'alarm_triggered':
          // 新增：报警开关控制，只有开启时才处理报警
          if (!alarmConfig.value.enabled) {
            break;
          }
          // 增加保护，防止无效的报警数据导致问题
          if (!data || !data.message) {
            console.error("接收到无效的报警数据，已忽略:", e.data);
            break;
          }
          // 存储报警信息到indexDb
          const alarmRecord = {
            date: new Date().toLocaleString(),
            info: data.message,
            deviceId: data.deviceId,
            sensorType: data.sensorType,
            sensorIndex: data.sensorIndex,
            value: data.value,
            actualValue: data.actualValue || 0, // 存储实际数值
            timestamp: data.timestamp,
            gatewayIp: data.gatewayIp || currentIp.value || '未知网关',
            gatewayName: data.gatewayName,
            level: 'error',
            status: 'active'
          };

          // 保存到indexDb
          try {
            // 成功保存后，再更新UI
            await indexDb.addData(alarmRecord)
            user_store.updateIndexDbNum(indexDbNum.value + 1)
            isOpenDrawer.value = true
            saveErrorInfoWorker?.postMessage({
               type: 'save_error_info',
               data: {
                 alarmRecord
               }
            })
            
          } catch (error) {
            console.error('保存报警信息失败:', error);
          }
          break;
          
        case 'alarm_cleared':
          // 报警解除
            // 存储报警解除信息到indexDb
          const clearRecord = {
            
            date: new Date().toLocaleString(),
            info: data.message,
            deviceId: data.deviceId,
            sensorType: data.sensorType,
            sensorIndex: data.sensorIndex,
            value: 0, // 恢复正常状态
            actualValue: data.actualValue || 0,
            timestamp: data.clearedAt,
            gatewayIp: data.gatewayIp || currentIp.value || '未知网关',
            gatewayName: data.gatewayName || (gateway_store.gatewayList.find(g => g.ip === currentIp.value)?.name || '未知网关'),
            level: 'success',
            status: 'cleared'
          };
          
          try {
            await indexDb.addData(clearRecord);
            indexDbNum.value += 1
            saveErrorInfoWorker?.postMessage({
               type: 'save_error_info',
               data: {
                 clearRecord
               }
            })
          } catch (error) {
            console.error('保存报警解除信息失败:', error);
          }
          
          // 显示解除通知
          ElMessage({
            type: 'success',
            message: data.message,
            duration: 3000
          });
          break;
          
        case 'voice_alarm':
          // 语音播报
          if (alarmConfig.value.voiceEnabled && message) {
            playVoiceAlarm(message);
          }
          break;
          
        case 'save_alarm_log':
          // 将报警日志发送给saveErrorInfoWorker
          if (saveErrorInfoWorker.value) {
            saveErrorInfoWorker.value.postMessage({
              type: 'save_error_info',
              data: {
                alarmRecord: {
                  level: data.level,
                  actualValue: data.actualValue,
                  deviceId: data.deviceId,
                  sensorIndex: data.sensorIndex,
                  info: data.message,
                  gatewayIp: data.gatewayIp,
                  gatewayName: data.gatewayName,
                  customName: data.customName
                }
              }
            });
          }
          break;
          
        case 'alarm_data_updated':
          // 报警数据更新（冷却期内的数据更新）
          // 更新活跃报警列表中的数据
          const updatedAlarmIndex = activeAlarms.value.findIndex(
            alarm => alarm.deviceId === data.deviceId && 
                    alarm.sensorIndex === data.sensorIndex && 
                    alarm.gatewayIp === data.gatewayIp
          );
          if (updatedAlarmIndex !== -1) {
            activeAlarms.value[updatedAlarmIndex] = data;
          }
          
          // 可选：显示静默通知，告知用户数据已更新
          ElMessage({
            type: 'info',
            message: `${data.sensorType}传感器数据已更新 - 当前值: ${data.actualValue}, 最大值: ${data.maxValue}`,
            duration: 2000,
            showClose: true
          });
          break;
          
        case 'alarm_escalated':
          // 报警升级通知
          ElMessage({
            type: 'warning',
            message: `⚠️ 报警升级: ${data.escalationReason}`,
            duration: 5000,
            showClose: true
          });
          
          // 如果启用语音且升级严重，可以考虑语音提醒
          if (alarmConfig.value.voiceEnabled) {
            playVoiceAlarm(`报警升级提醒：${data.escalationReason}`);
          }
          break;
          
        case 'active_alarms_response':
          // 活跃报警响应
          activeAlarms.value = data;
          break;
          
        case 'worker_error':
          console.error('AlarmWorker错误:', data.error);
          break;
          
        case 'heartbeat_response':
          // 报警Worker心跳响应
          console.log('AlarmWorker心跳正常, 活跃报警数:', data.activeAlarmsCount);
          break;
          
        case 'get_system_stats':
          // 获取系统状态统计
          if (alarmWorker.value) {
            alarmWorker.value.postMessage({ type: 'get_system_stats' });
          }
          break;
          
        case 'system_stats_response':
          // 系统状态统计响应
          console.log('系统状态统计:', data);
          break;
      }
    };
    
    // 配置报警Worker
    alarmWorker.value.postMessage({
      type: 'update_config',
      data: {
        voiceEnabled: alarmConfig.value.voiceEnabled
      }
    });
    
    // 初始化语音合成
    if ('speechSynthesis' in window) {
      speechSynthesis.value = window.speechSynthesis;
    }
  }
};

// 语音播报函数
const playVoiceAlarm = (message: string) => {
  if (!speechSynthesis.value || !alarmConfig.value.voiceEnabled) {
    return;
  }
  
  try {
    // 停止当前播报
    speechSynthesis.value.cancel();
    
    // 创建语音播报
    const utterance = new SpeechSynthesisUtterance(message);
    utterance.lang = 'zh-CN'; // 中文
    utterance.rate = 1.0; // 语速
    utterance.pitch = 1.0; // 音调
    utterance.volume = 0.8; // 音量
    
    // 播报完成回调
    utterance.onend = () => {
      // 通知 alarmWorker 语音播报结束，继续处理队列
      if (alarmWorker.value) {
        alarmWorker.value.postMessage({ type: 'voice_ended' });
      }
    };
    
    utterance.onerror = (event) => {
      console.error('语音播报错误:', event.error);
      // 即使出错，也要通知 alarmWorker 继续处理队列，防止阻塞
      if (alarmWorker.value) {
        alarmWorker.value.postMessage({ type: 'voice_ended' });
      }
    };
    
    // 开始播报
    speechSynthesis.value.speak(utterance);
  } catch (error) {
    console.error('语音播报失败:', error);
  }
};

// 切换语音报警开关
const toggleVoiceAlarm = () => {
  alarmConfig.value.voiceEnabled = !alarmConfig.value.voiceEnabled;
  
  // 更新Worker配置
  if (alarmWorker.value) {
    alarmWorker.value.postMessage({
      type: 'update_config',
      data: {
        voiceEnabled: alarmConfig.value.voiceEnabled
      }
    });
  }
  
  ElMessage({
    type: 'info',
    message: `语音报警已${alarmConfig.value.voiceEnabled ? '开启' : '关闭'}`,
    duration: 2000
  });
};

// 清除所有报警
const clearAllAlarms = () => {
  if (alarmWorker.value) {
    alarmWorker.value.postMessage({ type: 'clear_all_alarms' });
  }
  activeAlarms.value = [];
};

// 启动心跳检测
const startWorkerHeartbeat = () => {
  if (workerHeartbeatTimer.value) {
    clearInterval(workerHeartbeatTimer.value);
  }
  
  workerHeartbeatTimer.value = setInterval(() => {
    if (!sensorDataWorker.value) return;
    
    // 发送心跳包
    (sensorDataWorker.value as Worker).postMessage({ type: 'heartbeat' });
    
    // 检查上次响应是否超时（5秒无响应）
    if (Date.now() - workerLastHeartbeat.value > 5000) {
      console.warn('Worker心跳响应超时，准备恢复');
      scheduleWorkerRecovery();
    }
    
    // 同时检查报警Worker心跳
    if (alarmWorker.value) {
      alarmWorker.value.postMessage({ type: 'heartbeat' });
    }
  }, 3000); // 每3秒发送一次心跳
};

// 停止心跳检测
const stopWorkerHeartbeat = () => {
  if (workerHeartbeatTimer.value) {
    clearInterval(workerHeartbeatTimer.value);
    workerHeartbeatTimer.value = null;
  }
};

function onAlarmControlClick() {
  toggleVoiceAlarm();
  ElMessage({
    type: 'success',
    message: alarmConfig.value.voiceEnabled ? '已开启语音报警' : '已关闭语音报警',
    duration: 2000
  });
}

// 图例数据
const sensorLegend = [
  { type: 4, label: '紫外', color: '#5470c6' },
  { type: 3, label: '红外', color: '#ee6666' },
  { type: 0, label: '温度', color: '#91cc75' },
  { type: 1, label: '湿度', color: '#fac858' },
  { type: 2, label: '压力', color: '#73c0de' },
]
const selectedLegend = ref<number | null>(null)
const isGatewayLevelStats = ref<boolean>(false) // 标识当前是否为网关级别统计

// 获取报警统计数据的通用函数
const getAlarmStats = async (type: number) => {
  const gateway_ip = currentIp.value;
  const isGatewayLevel = device_currentId.value === -1;
  
  // 更新状态指示器
  isGatewayLevelStats.value = isGatewayLevel;
  
  try {
    let res;
    if (isGatewayLevel) {
      // 网关级别统计：使用专门的网关统计接口
      res = await proxy.$adminHttp.get('/admin/getErrorStatsByType', {
        params: {
          gateway_ip,
          type: type // 注意这里参数名是type，不是type_id
        }
      });
    } else {
      // 监测点级别统计：只统计当前监测点的报警
      const module_id = device_currentId.value;
      res = await proxy.$adminHttp.get('/admin/getErrorStatsByModule', {
        params: {
          gateway_ip,
          module_id,
          type_id: type
        }
      });
    }
    // 处理返回数据
    if (!res.data || !res.data.data || res.data.data.length === 0) {
      barChartData.value = [];
      barChartXAxis.value = [];
      if (barChart) {
        barChart.dispose();
        barChart = null;
      }
      return;
    }
    
    // 更新图表数据
    barChartXAxis.value = res.data.data.map((xAxis: { date: string }) => xAxis.date);
    barChartData.value = res.data.data.map((data: { count: number }) => data.count);

    await nextTick();

    if (history_bar.value) {
      if (!barChart) {
        barChart = echarts.init(history_bar.value);
      }
      barChart.setOption({
        grid: { left: 40, right: 20, top: 60, bottom: 40, containLabel: true },
        xAxis: {
          type: 'category',
          data: barChartXAxis.value,
          axisLabel: { color: '#b0c4de', fontSize: 16, fontWeight: 'bold' },
          axisLine: { lineStyle: { color: '#3a4a6b' } }
        },
        yAxis: {
          type: 'value',
          axisLabel: { color: '#b0c4de', fontSize: 16 },
          splitLine: { lineStyle: { color: '#2c3652' } },
          axisLine: { show: false }
        },
        series: [{
          data: barChartData.value,
          type: 'bar',
          barWidth: '40%',
          itemStyle: {
            borderRadius: [8, 8, 0, 0],
            color: {
              type: 'linear',
              x: 0, y: 0, x2: 0, y2: 1,
              colorStops: [
                { offset: 0, color: '#5b8ff9' },
                { offset: 1, color: '#3a4a6b' }
              ]
            },
            shadowColor: 'rgba(91,143,249,0.3)',
            shadowBlur: 10
          },
          emphasis: {
            itemStyle: {
              color: '#ffb761',
              borderColor: '#fff',
              borderWidth: 2
            }
          },
          label: {
            show: true,
            position: 'top',
            color: '#fff',
            fontWeight: 'bold',
            fontSize: 16
          }
        }],
        tooltip: {
          trigger: 'axis',
          axisPointer: { type: 'shadow' },
          backgroundColor: '#222',
          borderColor: '#5b8ff9',
          borderWidth: 1,
          textStyle: { color: '#fff', fontSize: 14 }
        }
      }, true);
    }
  } catch (error) {
    console.error('获取报警统计数据失败:', error);
    barChartData.value = [];
    barChartXAxis.value = [];
    if (barChart) {
      barChart.dispose();
      barChart = null;
    }
  }
};



// 图例点击事件
const onLegendClick = async (type: number) => {
  selectedLegend.value = type;
  barChartType.value = type;
  
  // 根据当前状态决定是网关级别还是监测点级别统计
  // 这里可以根据业务需求调整，目前默认为监测点级别
  await getAlarmStats(type);
};

</script>

<style scoped lang="less">
main {
  padding: 10PX 5PX;
  height: calc(100vh - 100PX); /* Full viewport height minus custom titlebar (40px) and header (80px) */
}
.home-layout {
  display: flex;
  height: 100%;
  gap: 5px; /* Spacing between columns */
}

.left-column, .right-column {
  flex: 3;
  display: flex;
  flex-direction: column;
  gap: 10px;
  min-width: 0;
}

.middle-column {
  flex: 4;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  min-width: 0;
}

.my_chart, .right-charts {
  display: flex;
  flex-direction: column;
  flex-grow: 1;
  gap: 10px;
  // overflow-y: auto;
}
.right-charts {
  height: auto; /* Let flexbox handle height */
}

.chart-wrapper {
  flex: 1;
  min-height: 0;
  position: relative;

  &.zoomed {
    position: fixed;
    top: 0;
    left: 0;
    width: 100vw;
    height: calc(100vh - 40PX);
    z-index: 1000;
    margin-top: 40PX;
    background: #1d335d;
  }
}

.middle-header {
  /* margin-top: 20px; */ /* Removed to reduce top space */
  .title {        
    width: 100%;
    text-align: center;
    color: rgb(46, 192, 246);
    font-size: 30px;
    height: 70px;
    line-height: 70px;
  }
  .description {
    color: rgb(255, 255, 255);
    font-size: 20px;
    height: 30px;
    line-height: 30px;
    text-align: center;
  }
}

.mainCenter {
  padding: 0 10px;
  width: 100%;
  height: 100%;
  position: relative;
  display: flex;
  flex-direction: column;
  border: 0.008rem solid rgba(14,253,255,0.5);

  .total {
    display: flex;
    align-items: stretch;
    padding: 10px;
    box-sizing: border-box;
    // 图例和柱状图布局
    > div {
      flex-shrink: 0;
    }
    aside {
      flex: 1 1 0;
      min-width: 0;
      min-height: 220px;
      height: 100%;
      display: flex;
    }
    &.vertical-layout {
      flex-direction: column;
      > div, aside {
        width: 100%;
        min-width: 0;
      }
      aside {
        min-height: 180px;
        max-height: 320px;
        height: 100%;
      }
    }
  }
}

.gateway-selector {
  display: flex;
  justify-content: center;
  align-items: center;
  flex-wrap: wrap;
  margin-bottom: 15px;
  gap: 20px;
  min-height: 60px;
  width: 100%;
}
.gateway-btn {
  margin: 0;
  padding: 0 24px;
  height: 40px;
  border-radius: 20px;
  font-weight: bold;
  font-size: 18px;
  background: linear-gradient(135deg, #1de9b6 0%, #1dc8e9 100%);
  color: #fff;
  box-shadow: 0 2px 8px rgba(0,255,255,0.15);
  border: none;
  transition: all 0.2s;
  outline: none;
  opacity: 0.85;
  white-space: nowrap;
  display: flex;
  align-items: center;
  justify-content: center;
  &:hover {
    background: linear-gradient(135deg, #1dc8e9 0%, #1de9b6 100%);
    color: #ffe066;
    box-shadow: 0 4px 16px rgba(0,255,255,0.25);
    opacity: 1;
  }
  &.active {
    background: linear-gradient(135deg, #1dc8e9 0%, #1de9b6 100%);
    color: #fff;
    border: 2px solid #ffe066;
    box-shadow: 0 6px 24px rgba(0,255,255,0.35);
    opacity: 1;
  }
  &.el-button--primary {
    background: linear-gradient(135deg, #1de9b6 0%, #1dc8e9 100%) !important;
    color: #fff !important;
    opacity: 0.85;
    border: none;
  }
  &.active {
    opacity: 1 !important;
    color: #fff !important;
    border: 2px solid #ffe066 !important;
  }
  &.el-button--plain {
    background: rgba(29, 233, 182, 0.1) !important;
    color: #fff !important;
    opacity: 0.5;
  }
  &.is-disabled {
    background: #c4c4c4 !important;
    border-color: #9e9e9e !important;
    color: #fff !important;
    cursor: not-allowed;
    opacity: 0.6;
  }
}

.fab-cmd-center {
  position: fixed;
  right: 12px;
  bottom: 20px;
  width: 60px;
  height: 60px;
  background: linear-gradient(135deg, #1de9b6 0%, #1dc8e9 100%);
  color: #fff;
  border-radius: 50%;
  box-shadow: 0 4px 24px rgba(0,0,0,0.25);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 24px;
  cursor: pointer;
  z-index: 3000;
  transition: box-shadow 0.2s, background 0.2s;
}
.fab-cmd-center:hover {
  box-shadow: 0 8px 32px rgba(0,255,255,0.35);
  background: linear-gradient(135deg, #1dc8e9 0%, #1de9b6 100%);
  color: #ffe066;
}

.fab-alarm-control {
  position: fixed;
  bottom: 100px;
  right: 12px;
  width: 50px;
  height: 50px;
  background: linear-gradient(135deg, #ff6b6b 0%, #ee5a52 100%);
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  box-shadow: 0 4px 15px rgba(255, 107, 107, 0.3);
  transition: all 0.3s ease;
  z-index: 2999;
  color: white;
}

.fab-alarm-control:hover {
  transform: translateY(-2px);
  box-shadow: 0 6px 20px rgba(255, 107, 107, 0.4);
}

.fab-alarm-indicator {
  position: fixed;
  bottom: 160px;
  right: 12px;
  width: 50px;
  height: 50px;
  background: linear-gradient(135deg, #ff4757 0%, #ff3742 100%);
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  box-shadow: 0 4px 15px rgba(255, 71, 87, 0.4);
  transition: all 0.3s ease;
  z-index: 2998;
  color: white;
  animation: pulse 2s infinite;
}

.fab-alarm-indicator:hover {
  transform: translateY(-2px);
  box-shadow: 0 6px 20px rgba(255, 71, 87, 0.5);
}

@keyframes pulse {
  0% {
    box-shadow: 0 4px 15px rgba(255, 71, 87, 0.4);
  }
  50% {
    box-shadow: 0 4px 25px rgba(255, 71, 87, 0.7);
  }
  100% {
    box-shadow: 0 4px 15px rgba(255, 71, 87, 0.4);
  }
}

.alarm-badge {
  display: flex;
  align-items: center;
  justify-content: center;
}

.alarms-container {
  max-height: 500px;
  overflow-y: auto;
}

.alarms-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 20px;
  padding-bottom: 10px;
  border-bottom: 1px solid #ebeef5;
}

.no-alarms {
  text-align: center;
  padding: 40px 20px;
  color: #909399;
}

.no-alarms p {
  margin-top: 10px;
  font-size: 16px;
}

.alarms-list {
  display: flex;
  flex-direction: column;
  gap: 15px;
}

.alarm-item {
  display: flex;
  align-items: flex-start;
  padding: 15px;
  background: #fff;
  border: 1px solid #ff4757;
  border-radius: 8px;
  box-shadow: 0 2px 8px rgba(255, 71, 87, 0.1);
  transition: all 0.3s ease;
}

.alarm-item:hover {
  box-shadow: 0 4px 12px rgba(255, 71, 87, 0.2);
}

.alarm-icon {
  margin-right: 15px;
  flex-shrink: 0;
}

.alarm-content {
  flex: 1;
  min-width: 0;
}

.alarm-title {
  font-size: 16px;
  font-weight: 600;
  color: #303133;
  margin-bottom: 8px;
}

.alarm-details {
  display: flex;
  flex-wrap: wrap;
  gap: 15px;
  font-size: 14px;
  color: #606266;
}

.alarm-details span {
  white-space: nowrap;
}

.alarm-actions {
  margin-left: 15px;
  flex-shrink: 0;
}

.alarm-dialog-footer {
  display: flex;
  justify-content: flex-end;
  gap: 10px;
}

.my-context-menu {
  background: #222;
  color: #fff;
  border-radius: 4px;
  min-width: 120px;
  box-shadow: 0 2px 8px rgba(0,0,0,0.2);
  padding: 8px 0;
  position: fixed;
}
.my-context-menu > div {
  padding: 8px 16px;
  cursor: pointer;
}
.my-context-menu > div:hover {
  background: #444;
}

.chart-statistics-section {
  flex: 1 1 0;
  min-height: 220px;
  display: flex;
  flex-direction: row;
  align-items: stretch;
  justify-content: center;
  background: linear-gradient(180deg, rgba(40,60,120,0.12) 0%, rgba(30,40,80,0.18) 100%);
  border-radius: 18px;
  box-shadow: 0 4px 24px 0 rgba(40,60,120,0.08);
  position: relative;
}
.chart-statistics-legend-area {
  width: 120px;
  min-width: 100px;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  margin-right: 10px;
  justify-content: center;
  font-size: 16px;
}
.chart-statistics-title {
  font-size: 16px;
  font-weight: bold;
  color: #fff;
  margin-bottom: 18px;
  letter-spacing: 2px;
  text-shadow: 0 2px 8px #1d335d44;
}
.chart-statistics-bar-area {
  flex: 1 1 0;
  min-width: 0;
  min-height: 220px;
  height: 100%;
  display: flex;
  align-items: stretch;
  justify-content: center;
}
@media (max-height: 700px) {
  .chart-statistics-section {
    min-height: 180px;
    max-height: 320px;
  }
  .chart-statistics-bar-area {
    min-height: 120px;
    max-height: 220px;
  }
}
// 在样式末尾补充：
@media (min-height: 900px) {
  .chart-statistics-section {
    background: linear-gradient(180deg, rgba(40,60,120,0.18) 0%, rgba(30,40,80,0.28) 100%);
    min-height: 400px;
    max-height: 900px;
    align-items: center;
    justify-content: center;
  }
  .chart-statistics-bar-area {
    min-height: 320px;
    max-height: 800px;
  }
}

.chart-statistics-tip {
  color: #ffb761;
  font-size: 14px;
  margin-bottom: 6px;
}

.bar-chart-title {
  text-align: center;
  font-size: 20px;
  font-weight: bold;
  color: #fff;
  margin-bottom: 10px;
  letter-spacing: 2px;
}
.bar-chart-legend {
  display: flex;
  justify-content: center;
  align-items: center;
  margin-bottom: 10px;
  gap: 18px;
}
.bar-chart-legend span {
  cursor: pointer;
  color: #aaa;
  font-size: 15px;
  font-weight: normal;
  .legend-dot {
    display: inline-block;
    width: 14px;
    height: 14px;
    border-radius: 50%;
    margin-right: 6px;
    vertical-align: middle;
  }
}
.bar-chart-legend .active {
  color: #fff;
  font-weight: bold;
  text-shadow: 0 2px 8px #1d335d44;
}
.bar-chart-echarts {
    flex: 1;
    min-height: 220px;
    max-height: 500px;
    width: 100%;
  }

/* 新增：报警详情样式 */
.alarm-details {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 8px;
}

.detail-item {
  display: inline-block;
  padding: 2px 6px;
  background-color: #f5f7fa;
  border-radius: 4px;
  font-size: 12px;
  color: #606266;
  border: 1px solid #e4e7ed;
}

.detail-item.current-value {
  background-color: #e1f3ff;
  border-color: #409eff;
  color: #409eff;
}

.detail-item.max-value {
  background-color: #fef0f0;
  border-color: #f56c6c;
  color: #f56c6c;
}

.detail-item.max-value strong {
  font-weight: bold;
  font-size: 13px;
}

.detail-item.alarm-count {
  background-color: #fff7e6;
  border-color: #e6a23c;
  color: #e6a23c;
}

.count-badge {
  display: inline-block;
  background-color: #e6a23c;
  color: white;
  border-radius: 10px;
  padding: 1px 6px;
  font-size: 11px;
  font-weight: bold;
  margin-left: 4px;
}

.detail-item.last-update {
  background-color: #f0f9ff;
  border-color: #67c23a;
  color: #67c23a;
}

.alarms-container {
  max-height: 500px;
  overflow-y: auto;
}

.alarm-item {
  display: flex;
  align-items: flex-start;
  padding: 16px;
  border: 1px solid #ebeef5;
  border-radius: 8px;
  margin-bottom: 12px;
  background-color: #fafafa;
  transition: all 0.3s ease;
}

.alarm-item:hover {
  background-color: #f5f7fa;
  border-color: #c0c4cc;
}

.alarm-icon {
  margin-right: 12px;
  flex-shrink: 0;
}

.alarm-content {
  flex: 1;
  min-width: 0;
}

.alarm-title {
  font-weight: 500;
  color: #303133;
  margin-bottom: 8px;
  line-height: 1.4;
}

.alarm-actions {
  margin-left: 12px;
  flex-shrink: 0;
}

/* 统计级别指示器样式 */
.stats-level-indicator {
  display: flex;
  align-items: center;
  padding: 6px 12px;
  margin: 8px 0;
  border-radius: 20px;
  font-size: 12px;
  font-weight: 500;
  transition: all 0.3s ease;
  border: 1px solid;
}

.stats-level-indicator.gateway-level {
  background-color: #e8f4fd;
  border-color: #409eff;
  color: #409eff;
}

.stats-level-indicator.device-level {
  background-color: #f0f9ff;
  border-color: #67c23a;
  color: #67c23a;
}

.level-icon {
  margin-right: 6px;
  font-size: 14px;
}

/* 空状态提示样式 */
.chart-container {
  position: relative;
  width: 100%;
}

.empty-chart-state {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 20px;
}

.empty-icon {
  margin-bottom: 16px;
  opacity: 0.6;
}

.empty-text {
  color: #909399;
}

.empty-title {
  font-size: 16px;
  font-weight: 500;
  margin: 0 0 8px 0;
  color: #606266;
}

.empty-description {
  font-size: 14px;
  margin: 0 0 12px 0;
  color: #909399;
}

.empty-tip {
  font-size: 12px;
  margin: 0;
  color: #c0c4cc;
  font-style: italic;
}

.stats-level-indicator.device-level {
  background-color: #f0f9ff;
  border-color: #67c23a;
  color: #67c23a;
}

.level-icon {
  margin-right: 6px;
  font-size: 14px;
}

.level-text {
  font-weight: 600;
}

</style>